home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / tail.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  2KB  |  146 lines

  1. /* tail - print the end of a file */
  2.  
  3. #include <stdio.h>
  4.  
  5. #define TRUE 1
  6. #define FALSE 0
  7. #define BLANK ' '
  8. #define TAB '\t'
  9. #define NEWL '\n'
  10.  
  11. int lines, chars;
  12. char buff[BUFSIZ];
  13.  
  14. main(argc, argv)
  15. int argc;
  16. char *argv[];
  17. {
  18.   char *s;
  19.   FILE *input, *fopen();
  20.   int count;
  21.  
  22.   setbuf(stdout, buff);
  23.   argc--;
  24.   argv++;
  25.   lines = TRUE;
  26.   chars = FALSE;
  27.   count = -10;
  28.  
  29.   if (argc == 0) {
  30.     tail(stdin, count);
  31.     exit(0);
  32.   }
  33.   s = *argv;
  34.   if (*s == '-' || *s == '+') {
  35.     s++;
  36.     if (*s >= '0' && *s <= '9') {
  37.         count = stoi(*argv);
  38.         s++;
  39.         while (*s >= '0' && *s <= '9') s++;
  40.     }
  41.     if (*s == 'c') {
  42.         chars = TRUE;
  43.         lines = FALSE;
  44.     } else if (*s != 'l' && *s != '\0') {
  45.         fprintf(stderr, "tail: unknown option %c\n", *s);
  46.         argc = 0;
  47.     }
  48.     argc--;
  49.     argv++;
  50.   }
  51.   if (argc < 0) {
  52.     fprintf(stderr, "Usage: tail [+/-[number][lc]] [files]\n");
  53.     exit(1);
  54.   }
  55.   if (argc == 0) tail(stdin, count);
  56.  
  57.   else if ((input = fopen(*argv, "r")) == NULL) {
  58.     fprintf(stderr, "tail: can't open %s\n", *argv);
  59.     exit(1);
  60.   } else {
  61.     tail(input, count);
  62.     fclose(input);
  63.   }
  64.  
  65.   exit(0);
  66. }
  67.  
  68. /* Stoi - convert string to integer */
  69. stoi(s)
  70. char *s;
  71. {
  72.   int n, sign;
  73.  
  74.   while (*s == BLANK || *s == NEWL || *s == TAB) s++;
  75.  
  76.   sign = 1;
  77.   if (*s == '+')
  78.     s++;
  79.   else if (*s == '-') {
  80.     sign = -1;
  81.     s++;
  82.   }
  83.   for (n = 0; *s >= '0' && *s <= '9'; s++) n = 10 * n + *s - '0';
  84.   return(sign * n);
  85. }
  86.  
  87. /* Tail - print 'count' lines/chars */
  88.  
  89. #define INCR(p)  if (p >= end) p=cbuf ; else p++
  90. #define BUF_SIZE 4098
  91.  
  92. char cbuf[BUF_SIZE];
  93.  
  94. tail(in, goal)
  95. FILE *in;
  96. int goal;
  97. {
  98.   int c, count;
  99.   char *start, *finish, *end;
  100.  
  101.   count = 0;
  102.  
  103.   if (goal > 0) {        /* skip */
  104.     count++;        /* start counting at 1 */
  105.     if (lines)        /* lines */
  106.         while ((c = getc(in)) != EOF) {
  107.             if (c == NEWL) count++;
  108.             if (count >= goal) break;
  109.         }
  110.     else            /* chars */
  111.         while (getc(in) != EOF) {
  112.             count++;
  113.             if (count >= goal) break;
  114.         }
  115.     if (count >= goal) while ((c = getc(in)) != EOF)
  116.             putc(c, stdout);
  117.   } else {            /* tail */
  118.  
  119.     goal = -goal;
  120.     start = finish = cbuf;
  121.     end = &cbuf[BUF_SIZE - 1];
  122.  
  123.     while ((c = getc(in)) != EOF) {
  124.         *finish = c;
  125.         INCR(finish);
  126.  
  127.         if (start == finish) INCR(start);
  128.         if (!lines || c == NEWL) count++;
  129.  
  130.         if (count > goal) {
  131.             count = goal;
  132.             if (lines) while (*start != NEWL)
  133.                     INCR(start);
  134.             INCR(start);
  135.         }
  136.     }            /* end while */
  137.  
  138.     while (start != finish) {
  139.         putc(*start, stdout);
  140.         INCR(start);
  141.     }
  142.  
  143.   }                /* end else */
  144.  
  145. }                /* end tail */
  146.